home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / Font Handler / TwoByteFonts.c < prev   
Encoding:
C/C++ Source or Header  |  2000-09-28  |  5.6 KB  |  194 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        TwoByteFonts.c
  3.  
  4.      Contains:    QuickDraw GX to PostScript conversion code.
  5.                          File contains code necessary for construction and use
  6.                         of Two Byte fonts (type-0) in PostScript.
  7.  
  8.      Version:    Technology:    Quickdraw GX 1.1.x
  9.       
  10.      Copyright:    © 1991-1997 by Apple Computer, Inc., all rights reserved.
  11. */
  12.  
  13. #include "GXToPSBuildConfig.h"
  14. #include <string.h>
  15. #include "IOUtilities.h"
  16. #include "GXExceptions.h"
  17. #include "GXPrintingUniverse.h"
  18. #include "FontDatabase.h"
  19. #include "FontHandler.h"
  20. #include "FontHandlerPrivate.h"
  21. #include "FontHandlerVariations.h"
  22. #include "FHResources.h"
  23. #include <GXGraphics.h>
  24.  
  25. #ifdef resumeLabel
  26.     #undef resumeLabel
  27. #endif
  28. #define resumeLabel(exception)
  29.  
  30.  
  31. //<FF>
  32. /*******************************************
  33.  
  34.     Routine counts how many glyphs are used by the
  35.     document for theFont.
  36.     
  37. ********************************************/
  38. OSErr FHCountDocGlyphs(TFontHandlerHdl hFHRec, fhFont theFont, long *nDocGlyphs);
  39. OSErr FHCountDocGlyphs(TFontHandlerHdl hFHRec, fhFont theFont, long *nDocGlyphs)
  40.     {
  41.         OSErr                        status;
  42.         gxFont                    realFont;
  43.         long                        glyphCount;
  44.         long                        dbIndex;
  45.         unsigned long        *glyphBits;
  46.         
  47.         realFont = FHGetSnapShotFont(hFHRec, theFont, &dbIndex);
  48.         glyphCount = GXCountFontGlyphs(realFont);
  49.         
  50.         status = FontDbaseGetGlyphBits((*hFHRec)->docDbase, realFont, dbIndex, &glyphBits, nil);
  51.         nrequire(status, failed_getBits);
  52.  
  53.         *nDocGlyphs = CountGlyphBits(glyphBits, glyphCount);
  54.  
  55. failed_getBits:
  56.         return(status);
  57.         
  58.         
  59.     }//FHCountDocGlyphs
  60.     
  61.     
  62. //<FF>
  63. /***************************************
  64.  
  65.     Function: FHGenerateTwoByteFontName
  66.     
  67.     Function generates the name for a synthetic Two Byte font
  68.     for a particular document font.
  69.  
  70. ****************************************/
  71. long FHGenerateTwoByteFontName(TFontHandlerHdl hFHRec, fhFont theFont, unsigned char name[256])
  72.     {
  73. #pragma unused(hFHRec)
  74.         long                                 nameLength;
  75.         
  76.         memcpy(name, "GX2ByteFont$", 11);                                                                            // base for name is /GX2ByteFont$
  77.         HexBlockMove((unsigned char*)&theFont, name + 11, sizeof(fhFont));        // Suffix is hex of theFont
  78.         
  79.         nameLength = 11 + 2 * sizeof(fhFont);
  80.         
  81.         return(nameLength);
  82.     
  83.     }//FHGenerateTwoByteFontName
  84.  
  85.  
  86.  
  87. //<FF>
  88. /****************************************************
  89.  
  90.     Function:        FHMakeTwoByteFont
  91.     
  92.     Function makes a two byte PostScript font out of all of the 
  93.     printer fonts for a particular real font if it is possible.
  94.     
  95.         It is possible if:
  96.             1:        The printer can support two byte fonts.
  97.             2:        There is more than one printer font for the document font.
  98.             3:        All Printer Fonts for the document font are resident and encoded on the printer.
  99.                             Two byte font will be made out of all printer fonts indexed zero through N where
  100.                             N is the biggest index of a printer font that is resident and encoded.
  101.  
  102.         hFHRec:            Handle to the font handler context.
  103.         theFont:        The font to make the two byte font from.
  104.  
  105. *****************************************************/
  106. OSErr FHMakeTwoByteFont(TFontHandlerHdl hFHRec, fhFont theFont)
  107.     {
  108.         OSErr                                status = noErr;
  109.         TPrinterFontRec            *printerFont;
  110.         long                                nPrFonts;                        // Number of printer fonts for the font.    
  111.         unsigned char                fontName[256];            // Name for a particular printer font.
  112.         long                                nameLength;                    // length of a name.
  113.         long                                idx;
  114.         Boolean                            buildFont = false;    // Should we build the font at all?
  115.         TRDParams                        rdParams;
  116.         long                                nDocGlyphs;
  117.         
  118.         rdParams.rdMap = (*hFHRec)->rdMap;
  119.         rdParams.resType = kScriptResType;
  120.         rdParams.resID = kFHScriptResID;
  121.         rdParams.rdFlags = eRDnoOptions;
  122.         
  123.         nPrFonts = FHCountPrinterFonts(hFHRec, theFont);
  124.  
  125.         /** No use making one if we don't need it or the printer can't support it **/
  126.         if ( (nPrFonts <= 1) || !((*hFHRec)->useTypeZeroFonts) )
  127.             return(noErr);
  128.             
  129.         /**
  130.             If the probability of needing to swap printer fonts is less 
  131.             than 25% don't bother with two byte font.  (# glyphs in doc < 384)
  132.             Trying guestimage when swapping fonts will be more efficient than
  133.             always using 2 byte strings for text.
  134.         **/
  135.         status = FHCountDocGlyphs(hFHRec, theFont, &nDocGlyphs);
  136.         nrequire(status, failed_count);        
  137.         if (nDocGlyphs < 384)
  138.             return(noErr);
  139.         
  140.                                 
  141.         /** Put the font dictionary for each printer font in the group on the operand stack **/
  142.         
  143.         for (idx = 0; idx < nPrFonts; ++idx) {
  144.  
  145.             status = FHGetIndexedPrinterFont(hFHRec, theFont, idx, &printerFont, nil);
  146.             nrequire(status, failed_GetPrFont);
  147.             
  148.             /** Only group toghether printer fonts that are encoded (and not already two byte fonts) **/
  149.             
  150.             if ( (printerFont->info & fontIsEncoded) && !(printerFont->info & fontCantBeRencoded) ) {
  151.             
  152.                 printerFont->info |= fontIsTwoByteMember;                                        // Mark as two byte font member.
  153.     
  154.                 nameLength = FHGeneratePrinterName(printerFont, fontName);        // Watch for hFHRec moving - if it can, lock it.
  155.                 rdParams.resIndex = kFindFont;
  156.                 status = RDResPrintf(&rdParams, fontName, nameLength);
  157.                 nrequire(status, failed_findFont);
  158.                 buildFont = true;
  159.                 
  160.             } else {
  161.             
  162.                 /****
  163.                     If we found a printer font that wasn't encoded, exit the loop
  164.                     We will build two byte font for first N fonts in group,
  165.                     rest will be handled by swapping
  166.                 ****/
  167.                 break;
  168.             
  169.             }//end if
  170.  
  171.         }//end for
  172.         
  173.         /** If we can build it, do it! **/
  174.         
  175.         if (buildFont) {
  176.         
  177.             /* Now build the two byte font out of all of the font dictionaries on the stack */
  178.             
  179.             nameLength = FHGenerateTwoByteFontName(hFHRec, theFont, fontName);
  180.             rdParams.resIndex = kMakeComposite;
  181.             status = RDResPrintf(&rdParams, nPrFonts, fontName, nameLength);        // Call MakeCompositeFont in PS.
  182.             nrequire(status, failed_makeComposite);
  183.             
  184.         }//end if
  185.     
  186. failed_count:
  187. failed_makeComposite:
  188. failed_findFont:
  189. failed_GetPrFont:
  190.  
  191.         return(status);
  192.     
  193.     }//FHMakeTwoByteFont
  194.